<?php

/**
 * Celebrio FileSystem module
 *
 * @copyright  Copyright (c) 2011 Celebrio Software
 * @package    Celebrio
 * @subpackage FileSystem
 */

namespace ApplicationsModule\GalleryModule;

use Nette\Object;
use \dibi;
use Nette\Web\User;
use Nette\Environment;

use ApplicationsModule\GalleryModule\PicasaWebLite;
use ApplicationsModule\GalleryModule\IGalleryDriver;

/**
 * Description of PicasaWeb
 *
 * @author honza
 */
class PicasaWeb extends Object implements IGalleryDriver {
    
    
    //377304209821.apps.googleusercontent.com;
    //EzJdyoeSzjSKgflKnBSP6KO1;
    
    const DEFAULT_FEED_URL = "https://picasaweb.google.com/data/feed/api";
    const DEFAULT_URL = "https://picasaweb.google.com/data/feed/api/user/default";
    
    private $token = "";
    private $user = null;
    private $picasaLite = null;
    protected static $client_id;
    protected static $client_secret;
    
    
    /**
     * Construct. This class works without token retrieved in constructor
     * so it is pointless to send it there.
     * 
     * @param type $access_token 
     */
    public function __construct($access_token = null) {
        $this->token = $access_token;
    }

    /**
     * Just test function. Can be deleted for commercial use
     * 
     * @return type mixin
     */
    public function test() {
        //$x = file_get_contents("http://www.google.com");
        $lite = new PicasaWebLite;
        $result = $lite->loadAlbumSamples(self::DEFAULT_URL, $this->token);
        //$response = simplexml_load_file("https://picasaweb.google.com/data/feed/api/user/default?oauth_token=1/ExjNgHn88NKQTOHkfLKVnRtyDv9yVkypBqwsJd4PSPY");
        
        return $result;
    }
    
    /**
     * Saves refresh token from picasa to DB.
     * There can be only one token for user.
     * 
     * @param string $token is refresh token from picasa.
     */
    public function saveToken($token) {
        $args = array(
            "user_id" => $this->user->getIdentity()->id,
            "token" => $token
        );
        dibi::query("INSERT INTO [gallery_picasa_token]", $args);

    }
    
    /**
     * Get token for authenticated user from DB
     * 
     * @return string $token token for user
     */
    private function getTokenFromDB() {
        $id_user = $this->user->getIdentity()->id;
        $fluent = dibi::select("token")->from("gallery_picasa_token")->where("user_id = %i", $id_user);
        $result = $fluent->execute();
        $token = $result->fetchSingle();
        return $token;
    }
    
    /**
     * Check if token is in DB for authenticated user and return true if yes,
     * otherwise false.
     * 
     * @return bool 
     */
    public function checkAvailability() {
        $token = $this->getTokenFromDB();
        if($token === false) {
            throw new PicasaTokenNotReachableException("Token is not in DB");
        }
        return true;
    }
    
    /**
     * Call picasaLite and gets albums for authenticated user
     * 
     * @return array[PicasaAlbum] array of picasa albums
     */
    public function loadAlbums() {
        $lite = $this->getPicasaLite();
        $token = $this->getAccessToken();
        return $lite->loadAlbumSamples(self::DEFAULT_URL, $token);
    }

    public function loadPhotosFromAlbum($albumID, $userID) {
        $lite = $this->getPicasaLite();
        $token = $this->getAccessToken();
        $url = $this->makeUrlForAlbum($albumID, $userID);
        return $lite->loadPhotosFromAlbum($url, $token);
    }
    
    public function createAlbum($name) {
        
    }

    
    /**
     * User setter
     * @param User $user 
     */
    public function setUser(User $user) {
        $this->user = $user;
    }
    
    /**
     * If is token in session (is valide and alive) returns it.
     * If there is no token in session it asks google for new short-live
     * access token.
     * 
     * @return string short-live access token from google
     */
    private function getAccessToken() {
        //TODO: save access token to session instead of getting everytime new token from google?
        $token = $this->getTokenFromSession();
        if($token !== null) {
            return $token;
        }
        $refresh_token = $this->getTokenFromDB();
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, "https://accounts.google.com/o/oauth2/token");
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $options = array(
            "client_id" => self::$client_id,
            "client_secret" => self::$client_secret,
            "refresh_token" => $refresh_token,
            "grant_type" => "refresh_token"
        );
        curl_setopt($ch, CURLOPT_POSTFIELDS, $options);
        $response_json = curl_exec($ch);
        curl_close($ch);
        $json = json_decode($response_json);
        $this->setTokenSession($json->access_token);
        return $json->access_token;
    }
    
    /**
     * Gets session for picasa
     * 
     * @return session 
     */
    private function getSession() {
        
        return Environment::getSession("picasa");
    }
    
    /**
     * Returns token from session
     * 
     * @return string token
     */
    private function getTokenFromSession() {
        $token = $this->getSession()->token;
        return $token;
    }
    
    /**
     * Set token to session (picasa) and sets expiration.
     * Basicly token live is about hour but to be sure this function sets
     * 50 minutes to expiration of session
     * 
     * @param string $access_token 
     */
    private function setTokenSession($access_token) {
        $session = $this->getSession();
        $session->token = $access_token;
        $session->setExpiration(3000);
    }
    
    /** 
     * Lazy getter for PicasaWebLite class
     * @return PicasaWebLite 
     */
    private function getPicasaLite() {
        if($this->picasaLite === null) {
            return new PicasaWebLite();
        }
        return $this->picasaLite;
    }
    
    private function makeUrlForAlbum($galleryID, $userID) {
        return self::DEFAULT_FEED_URL . 
                "/user/" . $userID . 
                "/albumid/" . $galleryID;
    }
    
    public static function setConnectionSettings(array $configuration) {
        self::$client_id = $configuration["client_id"];
        self::$client_secret = $configuration["client_secret"];
    }
    
    //TODO: discus if this is correct
    public static function getConnectionSettings() {
        return array("client_id" => self::$client_id, "client_secret" => self::$client_secret);
    }
    
    public function getGalleryNames() {
        //TODO: implement
        return array();
    }
}
